import * as PIXI from 'pixi.js'

export default class Mini3d {
  constructor() {
    this.view = new PIXI.Container()
    this.view.position.set(window.innerWidth / 2, window.innerHeight / 2)
    this.position3d = { x: 0, y: 0, z: 0 }
    this.rotation3d = { x: 0, y: 0, z: 0 }
    this.children = []
    // 焦距
    this.focalLength = 400
  }

  addChild(object) {
    // object.anchor.set(0.5)
    this.view.addChild(object)
    this.children.push(object)
  }

  depthSort(t, e) {
    return t.depth - e.depth
  }

  update() {
    // 通过三维坐标旋转，再通过焦距计算比例，然后调整每一个云的位置
    let sinX = Math.sin(this.rotation3d.x),
      cosX = Math.cos(this.rotation3d.x),
      sinY = Math.sin(this.rotation3d.y),
      cosY = Math.cos(this.rotation3d.y),
      sinZ = Math.sin(this.rotation3d.z),
      cosZ = Math.cos(this.rotation3d.z)
    for (let i = 0; i < this.children.length; i++) {
      let child = this.children[i]
      let offsetX = child.position3d.x - this.position3d.x
      let offsetY = child.position3d.y - this.position3d.y
      let offsetZ = child.position3d.z - this.position3d.z

      //X Axis Rotation 绕X旋转 x不变
      let offsetY2 = cosX * offsetY - sinX * offsetZ
      let offsetZ2 = sinX * offsetY + cosX * offsetZ

      //Y Axis Rotation  绕Y旋转 y不变
      let offsetZ3 = cosY * offsetZ2 - sinY * offsetX
      let offsetX3 = sinY * offsetZ2 + cosY * offsetX

      //Z Axis Rotation  绕Z旋转 z不变
      let offsetX4 = cosZ * offsetX3 - sinZ * offsetY2
      let offsetY4 = sinZ * offsetX3 + cosZ * offsetY2

      // 通过焦距计算比例
      let ratio = this.focalLength / (this.focalLength + offsetZ3)
      // 重新赋值新的距离
      offsetX = offsetX4 * ratio
      offsetY = offsetY4 * ratio
      offsetZ = offsetZ3

      // 计算缩放
      child.scale.x = child.scale.y = ratio * child.scaleRatio
      child.scale.x *= child.scaleOffset.x
      child.scale.y *= child.scaleOffset.y

      // 计算位置
      child.position.x = offsetX
      child.position.y = offsetY
      child.depth = -child.position3d.z
    }
    // 根据深度【也就是每个对象到屏幕的距离排序】
    this.view.children.sort(this.depthSort)
  }
}
